記錄學習內容。看網路上大大們的文章和影片,做些紀錄。
把這邊當作寫筆記的地方,內容可能有錯誤。
教學來源:
Java Concurrency Interview: Implement Scatter Gather pattern
情況:同時3個http執行緒執行,然後忽略3秒內沒完成http request的執行緒。
影片裡教了三種方法:
第一種方式 : threadPool和 thread.sleep
第二種方式 : CountDownLatch 和 latch.await
第三種方式 : CompletableFuture.runAsync
程式來自影片:
像是現在有3個http request 要去爬蟲 ,3秒內沒爬到的就不理。
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;
public class ThreadTest9 {
    static ExecutorService threadPool = Executors.newFixedThreadPool(4);
    //CountDownLatch  和 threadPool.submit
    private static Set<Integer> getPrices(int productId) throws InterruptedException {
        Set<Integer> prices = Collections.synchronizedSet(new HashSet<>());
        CountDownLatch latch = new CountDownLatch(3);
        threadPool.submit(new Task("google", productId, prices, latch));
        threadPool.submit(new Task("fb", productId, prices, latch));
        threadPool.submit(new Task("twitter", productId, prices, latch));
        // Thread.sleep(3*1000);
        //   latch.await();
        latch.await(3, TimeUnit.SECONDS); //3 seconds  或是 CountDownLatch變成0
        System.out.println("finished getPrices" + prices);
        return prices;
    }
    //CompletableFuture
    private static Set<Integer> getPrices1(int productId) throws InterruptedException, TimeoutException, ExecutionException {
        Set<Integer> prices = Collections.synchronizedSet(new HashSet<>());
        CompletableFuture<Void> task1 = CompletableFuture.runAsync(new Task("google", productId, prices));
        CompletableFuture<Void> task2 = CompletableFuture.runAsync(new Task("fb", productId, prices));
        CompletableFuture<Void> task3 = CompletableFuture.runAsync(new Task("twitter", productId, prices));
        CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2, task3);
        allTasks.get(3, TimeUnit.SECONDS);
        System.out.println("finished getPrices1" + prices);
        return prices;
    }
    //執行緒
    private static class Task implements Runnable {
        private String url;
        private int productId;
        private Set<Integer> prices;
        private CountDownLatch latch;
        public Task(String url, int productId, Set<Integer> prices, CountDownLatch latch) {
            this.url = url;
            this.productId = productId;
            this.prices = prices;
            this.latch = latch;
        }
        public Task(String url, int productId, Set<Integer> prices) {
            this.url = url;
            this.productId = productId;
            this.prices = prices;
            //this.latch = latch;
        }
        @Override
        public void run() {
            int price = (int) (Math.random() * 100) + 1;
            prices.add(price);
            try {
                //Thread.sleep(2000);  // 沒有timeout
                 Thread.sleep(4000); // 有timeout
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //  System.out.println("prices:" + prices);
            if (latch != null)
                latch.countDown();
        }
    }
    public static void main(String args[]) throws TimeoutException, ExecutionException {
        try {
            getPrices(5);
            getPrices1(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
結果(時間內沒完成):
finished getPrices[55, 75, 45]
Exception in thread "main" java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at ThreadTest9.getPrices1(ThreadTest9.java:39)
	at ThreadTest9.main(ThreadTest9.java:87)
結果(時間內完成):
finished getPrices[64, 4, 9]
finished getPrices1[7, 59, 95]